package naga.x.net.impl.pomelo;

import naga.x.App;
import naga.x.net.codec.PacketEncoder;
import naga.x.net.impl.pomelo.packet.ByteArrayPacket;
import naga.x.net.impl.pomelo.protocol.Message;
import naga.x.net.impl.pomelo.protocol.Package;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PomeloEncoder extends ProtocolEncoderAdapter implements PacketEncoder {

	protected static final Logger LOG = LoggerFactory.getLogger(PomeloEncoder.class);
	
	@Override
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
		Object buf = encode(session, message);
		if (buf != null) {
			out.write(buf);
		}
	}
	
	public static byte[] encode(PomeloPacket packet) {
		if (packet.getPackageType() != Package.TYPE_DATA) {
			return Package.encode(packet.getPackageType());
		}
		PomeloMessage ant = packet.getClass().getDeclaredAnnotation(PomeloMessage.class);
		if (ant == null) {
			LOG.error("[POMELO ENCODE]ROUTE NOT FOUND[" + packet.getClass().getName() + "]");
			return null;
		}
		if (ant.type() == null || ant.type() == Message.Type.REQUEST) {
			LOG.error("[POMELO ENCODE]MSG TYPE INVALID[" + packet.getClass().getName() + "]" + ant.type());
			return null;
		}
		String route = ant.type().msgHasRoute() ? ant.route() : null;
		boolean compressRoute = ant.type().msgHasRoute()
				&& App.getApp().getConfig().getDictionary().getRouteCode(route.toString()) != -1;
		Message msg = new Message(packet.getSerial(), ant.type(), compressRoute, route, packet, false);
		return Package.encode(packet.getPackageType(), msg);
	}

	@Override
	public Object encode(IoSession session, Object packet) {
		byte[] buf = null;
		if (packet instanceof ByteArrayPacket) {
			buf = ((ByteArrayPacket) packet).toByteArray();
		} else if (packet instanceof PomeloPacket) {
			buf = encode((PomeloPacket) packet);
		} else if (packet instanceof Package) {
			buf = Package.encode((Package) packet);
		} else if (packet instanceof Message) {
			buf = Package.encode(Package.TYPE_DATA, (Message) packet);
		} else if (packet instanceof byte[]) {
			buf = (byte[]) packet;
		}
		return buf;
	}

}
